/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package indexacion;

import buscador.IBuscador;
import buscador.InfoPalabra;
import java.io.*;
import java.util.ArrayList;
import java.util.HashMap;

/**
 *
 * @author acc_local
 */
public class Indice implements Serializable {
    
    private HashMap<String, ArrayList<InfoPalabra>> indice;
    int numeroDocsColeccion;
    private static final long serialVersionUID = 7526472295622776147L;
    
    public Indice() {
        this.indice = new HashMap<>();
        numeroDocsColeccion = 0;
    }
    
    public int getNumEntradasToken(String token) {
        if (indice.containsKey(token)) {
            return this.indice.get(token).size();
        } else {
            return 0;
        }
    }
    
    public int getNumDocumentosCol() {
        return this.numeroDocsColeccion;
    }
    
    protected void setNumDocumentosCol(int N) {
        this.numeroDocsColeccion = N;
    }
    
    public int getNumEntradas() {
        return this.indice.size();
    }
    
    public ArrayList<InfoPalabra> getOcurrencias(String token) {
        return this.indice.get(token);
    }
    
    public InfoPalabra getInfoPalabra(String palabra, int idDoc) {
        int idDocObservado;
        int contador = 0;
        boolean encontrado = false;
        InfoPalabra elEncontrado = null;
        
        if (indice.containsKey(palabra)) {
            ArrayList<InfoPalabra> listaOcurrencias = (ArrayList<InfoPalabra>) indice.get(palabra).clone();
            while (!encontrado && contador < listaOcurrencias.size()) {
                idDocObservado = listaOcurrencias.get(contador++).getIdDocumento();
                encontrado = (idDocObservado == idDoc);
            }
            if (encontrado) {
                contador--;
                elEncontrado = listaOcurrencias.get(contador);
            }
        }
        return elEncontrado;
    }
    
    protected void addEntrada(String token, int idDoc, String tituloDoc, int posDoc) {
        ArrayList<InfoPalabra> infoEntrada = indice.remove(token);
        InfoPalabra entradaPalabra = null;
        int contador = 0;
        boolean encontrado = false;

        // Cuando la entrada es nueva se crea una para él
        if (null == infoEntrada) {

            entradaPalabra = new InfoPalabra(idDoc, posDoc);
            infoEntrada = new ArrayList<>();
            infoEntrada.add(entradaPalabra);
            indice.put(token, infoEntrada);
        } // Si la entrada ya existe hay que actualizar su informacion en base a la información proporcionada
        else {
            do {
                entradaPalabra = infoEntrada.get(contador++);
                encontrado = entradaPalabra.matchDoc(idDoc);
            } while (!encontrado && contador < infoEntrada.size());
            // Se encontro una entrada que concuerda con el id y titulo indicados,
            // se actualiza la frecuencia de la entrada para ese documento
            if (encontrado) {
                entradaPalabra.actualizarFrecuencia();
                indice.put(token, infoEntrada);
            } else { // Si la palabra no tiene entrada se crea una nueva
                entradaPalabra = new InfoPalabra(idDoc, posDoc);
                infoEntrada.add(entradaPalabra);
                indice.put(token, infoEntrada);
            }
        }
    }
    public void almacenar() throws ExcepcionIndexacion {
        File fichero = new File(IBuscador.FICHERO_INDICE);
        ObjectOutputStream oos;
        
        try {
            if (fichero.exists() && fichero.delete()) {
                // Si ya existe se crea otro
                oos = new ObjectOutputStream(new FileOutputStream(IBuscador.FICHERO_INDICE, false));
                oos.writeObject(this);
                oos.close();  // Se cierra al terminar.
            } else {  // Si no existe, se crea con cabecera
                oos = new ObjectOutputStream(new FileOutputStream(IBuscador.FICHERO_INDICE, false));
                oos.writeObject(this);
                oos.close();  // Se cierra al terminar.
            }
        } catch (IOException ex) {
            throw new ExcepcionIndexacion("Problema al intentar almacenar el fichero de indice");
        }
    }
}
